using System;
using System.Collections.Generic;
using System.Xml;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace pginstaller.tasks
{
    public class MergeTranslationTemplates : Task
    {
        /* List of files to merge */
        [Required]
        public string[] Sources
        {
            get { return _sources; }
            set { _sources = value; }
        }

        /* Destination file to write to */
        [Required]
        public string Destination
        {
            get { return _destination; }
            set { _destination = value; }
        }

        /* Internal storage for the properties */
        private string[] _sources;
        private string _destination;
        
        /* Perform the actual build task */
        public override bool Execute()
        {
            Log.LogMessage("Merging template data into {0}", _destination);
            XmlDocument xDoc = null;
            Dictionary<string, bool> stringLookup = new Dictionary<string, bool>();
            int duplicates = 0;

            foreach (string src in _sources)
            {
                if (xDoc == null)
                {
                    xDoc = new XmlDocument();
                    xDoc.Load(src);

                    /* Load into a hashtable, because our strings are too complex to do xpath lookups on */
                    for (int i = 0; i < xDoc.DocumentElement.ChildNodes.Count; i++)
                    {
                        if (xDoc.DocumentElement.ChildNodes[i].NodeType != XmlNodeType.Element)
                            continue;
                        stringLookup.Add(xDoc.DocumentElement.ChildNodes[i].Attributes.GetNamedItem("original").Value, true);
                    }
                }
                else
                {
                    XmlReader rdr = XmlReader.Create(src);
                    while (rdr.Read())
                    {
                        if (rdr.Name == "string")
                        {
                            if (rdr.GetAttribute("original") != null)
                            {
                                if (stringLookup.ContainsKey(rdr.GetAttribute("original")))
                                    duplicates++;
                                else
                                {
                                    stringLookup.Add(rdr.GetAttribute("original"),true);
                                    XmlElement el = xDoc.CreateElement("string", "http://pginstaller.projects.postgresql.org/xmlns/translation");
                                    el.SetAttribute("original", rdr.GetAttribute("original"));
                                    el.SetAttribute("translation", "");
                                    xDoc.DocumentElement.AppendChild(el);
                                }
                            }
                        }
                    }
                    rdr.Close();
                }
            }
            Log.LogMessage("Merged {0}, total strings {1}, duplicate strings {2}", _destination, stringLookup.Count, duplicates);

            string enc = "UTF-8";
            if (xDoc.FirstChild.NodeType == XmlNodeType.XmlDeclaration)
                enc = ((XmlDeclaration)xDoc.FirstChild).Encoding;
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = "\t";
            settings.Encoding = System.Text.Encoding.GetEncoding(enc);
            XmlWriter xw = XmlWriter.Create(_destination, settings);

            xDoc.Save(xw);
            xw.Close();

            return true;
       }
    }
}